package com.insight.repository;

import com.insight.common.enums.ChangeType;
import com.insight.entity.MetadataTable;
import com.insight.entity.MetadataVersion;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;

/**
 * T052: MetadataVersion Repository接口
 * 元数据版本数据访问层,使用Spring Data JPA
 *
 * @author Insight Team
 */
@Repository
public interface MetadataVersionRepository extends JpaRepository<MetadataVersion, Long> {

    /**
     * 根据表查找所有版本记录
     *
     * @param table 表
     * @return 版本记录列表
     */
    List<MetadataVersion> findByTable(MetadataTable table);

    /**
     * 根据表ID查找所有版本记录
     *
     * @param tableId 表ID
     * @return 版本记录列表
     */
    @Query("SELECT mv FROM MetadataVersion mv WHERE mv.table.id = :tableId")
    List<MetadataVersion> findByTableId(@Param("tableId") Long tableId);

    /**
     * 根据表查找所有版本记录,按版本号降序排列
     *
     * @param table 表
     * @return 版本记录列表
     */
    List<MetadataVersion> findByTableOrderByVersionNumberDesc(MetadataTable table);

    /**
     * 根据表ID查找所有版本记录,按版本号降序排列
     *
     * @param tableId 表ID
     * @return 版本记录列表
     */
    @Query("SELECT mv FROM MetadataVersion mv WHERE mv.table.id = :tableId ORDER BY mv.versionNumber DESC")
    List<MetadataVersion> findByTableIdOrderByVersionNumberDesc(@Param("tableId") Long tableId);

    /**
     * 根据表和版本号查找版本记录
     *
     * @param table         表
     * @param versionNumber 版本号
     * @return 版本记录Optional
     */
    Optional<MetadataVersion> findByTableAndVersionNumber(MetadataTable table, Integer versionNumber);

    /**
     * 根据表ID和版本号查找版本记录
     *
     * @param tableId       表ID
     * @param versionNumber 版本号
     * @return 版本记录Optional
     */
    @Query("SELECT mv FROM MetadataVersion mv WHERE mv.table.id = :tableId AND mv.versionNumber = :versionNumber")
    Optional<MetadataVersion> findByTableIdAndVersionNumber(@Param("tableId") Long tableId, @Param("versionNumber") Integer versionNumber);

    /**
     * 查找表的最新版本记录
     *
     * @param table 表
     * @return 最新版本记录Optional
     */
    Optional<MetadataVersion> findFirstByTableOrderByVersionNumberDesc(MetadataTable table);

    /**
     * 查找表ID的最新版本记录
     *
     * @param tableId 表ID
     * @return 最新版本记录Optional
     */
    @Query("SELECT mv FROM MetadataVersion mv WHERE mv.table.id = :tableId ORDER BY mv.versionNumber DESC LIMIT 1")
    Optional<MetadataVersion> findLatestByTableId(@Param("tableId") Long tableId);

    /**
     * 查找表的最新版本号
     *
     * @param table 表
     * @return 最新版本号,如果没有版本则返回0
     */
    @Query("SELECT COALESCE(MAX(mv.versionNumber), 0) FROM MetadataVersion mv WHERE mv.table = :table")
    Integer findMaxVersionNumberByTable(@Param("table") MetadataTable table);

    /**
     * 查找表ID的最新版本号
     *
     * @param tableId 表ID
     * @return 最新版本号,如果没有版本则返回0
     */
    @Query("SELECT COALESCE(MAX(mv.versionNumber), 0) FROM MetadataVersion mv WHERE mv.table.id = :tableId")
    Integer findMaxVersionNumberByTableId(@Param("tableId") Long tableId);

    /**
     * 根据变更类型查找版本记录
     *
     * @param changeType 变更类型
     * @return 版本记录列表
     */
    List<MetadataVersion> findByChangeType(ChangeType changeType);

    /**
     * 根据表和变更类型查找版本记录
     *
     * @param table      表
     * @param changeType 变更类型
     * @return 版本记录列表
     */
    List<MetadataVersion> findByTableAndChangeType(MetadataTable table, ChangeType changeType);

    /**
     * 根据创建者查找版本记录
     *
     * @param createdBy 创建者
     * @return 版本记录列表
     */
    List<MetadataVersion> findByCreatedBy(String createdBy);

    /**
     * 分页查询指定表的版本记录
     *
     * @param table    表
     * @param pageable 分页参数
     * @return 版本记录分页结果
     */
    Page<MetadataVersion> findByTable(MetadataTable table, Pageable pageable);

    /**
     * 分页查询指定表ID的版本记录
     *
     * @param tableId  表ID
     * @param pageable 分页参数
     * @return 版本记录分页结果
     */
    @Query("SELECT mv FROM MetadataVersion mv WHERE mv.table.id = :tableId")
    Page<MetadataVersion> findByTableId(@Param("tableId") Long tableId, Pageable pageable);

    /**
     * 分页查询指定表的版本记录,按版本号降序排列
     *
     * @param table    表
     * @param pageable 分页参数
     * @return 版本记录分页结果
     */
    Page<MetadataVersion> findByTableOrderByVersionNumberDesc(MetadataTable table, Pageable pageable);

    /**
     * 查找指定时间范围内创建的版本记录
     *
     * @param startTime 开始时间
     * @param endTime   结束时间
     * @return 版本记录列表
     */
    List<MetadataVersion> findByCreatedAtBetween(LocalDateTime startTime, LocalDateTime endTime);

    /**
     * 查找指定表在时间范围内创建的版本记录
     *
     * @param table     表
     * @param startTime 开始时间
     * @param endTime   结束时间
     * @return 版本记录列表
     */
    List<MetadataVersion> findByTableAndCreatedAtBetween(MetadataTable table, LocalDateTime startTime, LocalDateTime endTime);

    /**
     * 查找指定版本号范围的版本记录
     *
     * @param table        表
     * @param fromVersion  起始版本号(包含)
     * @param toVersion    结束版本号(包含)
     * @return 版本记录列表
     */
    @Query("SELECT mv FROM MetadataVersion mv WHERE mv.table = :table " +
            "AND mv.versionNumber BETWEEN :fromVersion AND :toVersion " +
            "ORDER BY mv.versionNumber ASC")
    List<MetadataVersion> findByTableAndVersionNumberBetween(
            @Param("table") MetadataTable table,
            @Param("fromVersion") Integer fromVersion,
            @Param("toVersion") Integer toVersion);

    /**
     * 统计指定表的版本数量
     *
     * @param table 表
     * @return 版本数量
     */
    long countByTable(MetadataTable table);

    /**
     * 统计指定表ID的版本数量
     *
     * @param tableId 表ID
     * @return 版本数量
     */
    @Query("SELECT COUNT(mv) FROM MetadataVersion mv WHERE mv.table.id = :tableId")
    long countByTableId(@Param("tableId") Long tableId);

    /**
     * 统计指定表和变更类型的版本数量
     *
     * @param table      表
     * @param changeType 变更类型
     * @return 版本数量
     */
    long countByTableAndChangeType(MetadataTable table, ChangeType changeType);

    /**
     * 检查版本是否存在
     *
     * @param table         表
     * @param versionNumber 版本号
     * @return 是否存在
     */
    boolean existsByTableAndVersionNumber(MetadataTable table, Integer versionNumber);

    /**
     * 删除指定表的所有版本记录
     *
     * @param table 表
     */
    void deleteByTable(MetadataTable table);

    /**
     * 删除指定表ID的所有版本记录
     *
     * @param tableId 表ID
     */
    @Modifying
    @Transactional
    @Query("DELETE FROM MetadataVersion mv WHERE mv.table.id = :tableId")
    void deleteByTableId(@Param("tableId") Long tableId);

    /**
     * 删除指定版本号之前的所有版本记录(用于清理历史版本)
     *
     * @param table         表
     * @param versionNumber 版本号
     * @return 删除的记录数
     */
    @Modifying
    @Transactional
    @Query("DELETE FROM MetadataVersion mv WHERE mv.table = :table AND mv.versionNumber < :versionNumber")
    int deleteByTableAndVersionNumberLessThan(@Param("table") MetadataTable table, @Param("versionNumber") Integer versionNumber);

    /**
     * 批量保存版本记录
     * 重写saveAll方法以优化批量插入性能
     *
     * @param versions 版本记录列表
     * @return 保存后的版本记录列表
     */
    @Override
    <S extends MetadataVersion> List<S> saveAll(Iterable<S> versions);
}
